#pragma once
#include <jni.h>
#define FIND_CLASS(var, className) var = env->FindClass(className);

#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
  var = env->GetMethodID(clazz, methodName, methodDescriptor);

#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
  var = env->GetStaticMethodID(clazz, methodName, methodDescriptor);

#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
  var = env->GetFieldID(clazz, fieldName, fieldDescriptor);
namespace codec {

inline int jniRegisterNativeMethods(JNIEnv *env, const char *className,
                                    const JNINativeMethod *methods,
                                    int numMethods) {
  jclass clazz = env->FindClass(className);
  if (!clazz) return -1;
  int result = env->RegisterNatives(clazz, methods, numMethods);
  env->DeleteLocalRef(clazz);
  return result;
};
inline JavaVM *_vm;
inline JavaVM *getJvm() { return _vm; };
inline void setJvm(JavaVM *vm) { _vm = vm; };

struct ThreadEnvContext {
  JNIEnv *env = nullptr;
  bool attached = false;

  ~ThreadEnvContext() {
    if (attached && _vm) {
      _vm->DetachCurrentThread();
      attached = false;
    }
  }
};
inline JNIEnv *jniEnv() {
  // 使用线程本地存储（TLS）
  static thread_local ThreadEnvContext context;

  if (context.env) {
    return context.env;
  }

  // 尝试获取已附加的 JNIEnv
  jint status = _vm->GetEnv((void **)&context.env, JNI_VERSION_1_6);

  // 处理未附加线程
  if (status == JNI_EDETACHED) {
    JavaVMAttachArgs args = {
        .version = JNI_VERSION_1_6, .name = "NativeThread", .group = nullptr};

    if (_vm->AttachCurrentThread(&context.env, &args) == JNI_OK) {
      context.attached = true;
    }
  }

  // 检查异常状态
  if (context.env && context.env->ExceptionCheck()) {
    context.env->ExceptionDescribe();
    context.env->ExceptionClear();
  }

  return context.env;
};
}  // namespace codec